// 根据授权码从模拟api获取token,刷新token以及告知第三方解绑
import { AbstractPlatform } from '../AbstractPlatform';
import {getBrandConfig} from "../getBrandConfig";
import {MockThirdParty} from "../../mock/MockThirdParty";
import {AppDataSource} from "../../config/database";
import {BranchAccount} from "../../entity/BranchAccount";

export class XiaomiMock extends AbstractPlatform {
    private mockThirdParty: MockThirdParty;
    private config = getBrandConfig("xiaomi");

    constructor() {
        super();
        const config = getBrandConfig('xiaomi');
        this.mockThirdParty = new MockThirdParty(config.app_id, config.app_secret);
    }

    async exchangeToken(code: string): Promise<{ access_token: string; expires_in: number }> {
        this.logExchange('xiaomi', true);
        try {
            const response = await this.mockThirdParty.exchangeToken(code);
            return {
                access_token: response.access_token,
                expires_in: response.expires_in
            };
        } catch (e: any) {
            throw new Error(`Failed to exchange token: ${e.message}`);
        }
    }

    async revokeToken(token: string): Promise<void> {
        try {
            await this.mockThirdParty.revokeToken(token);
        } catch (error: any) {
            throw new Error(`Failed to revoke token: ${error.message}`);
        }
    }

    async refreshToken(userId: string, oldToken: string): Promise<{ access_token: string; expires_in: number }> {
        try {
            const response = await this.mockThirdParty.refreshToken(userId, oldToken);

            return {
                access_token: response.access_token,
                expires_in: response.expires_in,
            };
        } catch (error: any) {
            throw new Error(`Failed to refresh token: ${error.message}`);
        }
    }


    async getDeviceList(accessToken: string): Promise<{
        did: string;
        name: string;
        type: string;
        online: boolean;
    }[]> {
        const url = 'http://localhost:3000/xiaomi/devices';
        const appId = this.config.app_id;

        const res = await fetch(url, {
            method: 'GET',
            headers: {
                access_token: accessToken,
                app_id: appId
            }
        });

        const json = await res.json();

        if (res.status !== 200 || json.code !== 200) {
            throw new Error(`获取小米设备列表失败: ${json.message || res.status}`);
        }

        const deviceList = json.data.devices || [];

        return deviceList.map((item: any) => ({
            did: item.did,
            name: item.name,
            type: item.type,
            online: item.online
        }));
    }


    async subscribeDevice(accessToken: string, deviceId: string): Promise<void> {
        const reqUrl = 'http://localhost:3000/xiaomi/device/subscribe';
        const receiverUrl = 'http://localhost:3000/api/xiaomi/notify'; // 服务端的接收地址

        const res = await fetch(reqUrl, {
            method: 'POST',
            headers: {
                access_token: accessToken,
                app_id: this.config.app_id,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                did: deviceId,
                'receiver-url': receiverUrl
            })
        });

        const json = await res.json();

        if (res.status !== 200) {
            const code = json?.code || res.status;
            if (code === '001') {
                throw new Error(`小米订阅失败：设备不存在`);
            } else if (code === '903') {
                throw new Error(`小米订阅失败：授权过期`);
            } else {
                throw new Error(`小米订阅失败，错误码：${code}`);
            }
        }

        console.log(`[SUBSCRIBE] Xiaomi 设备 ${deviceId} 订阅成功`);
    }


    async revokeDeviceSubscription(userId: string, deviceId: string): Promise<void> {
        const tokenRepo = AppDataSource.getRepository(BranchAccount);
        const record = await tokenRepo.findOne({where: {userId, brand: 'xiaomi'}});

        if (!record) throw new Error(`未找到小米授权信息`);

        const res = await fetch('http://localhost:3000/xiaomi/device/subscribe/cancel', {
            method: 'POST',
            headers: {
                access_token: record.token,
                app_id: this.config.app_id,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                did: deviceId
            })
        });

        const json = await res.json();

        if (res.status !== 200) {
            throw new Error(`Xiaomi取消订阅失败: ${res.status}`);
        }

        if (json.code === '001') {
            throw new Error(`设备不存在`);
        } else if (json.code === '903') {
            throw new Error(`授权过期`);
        }

        console.log(`[UNSUB] Xiaomi 设备 ${deviceId} 取消订阅成功`);
    }



    async controlDevice(
        did: string,
        operation: string,
        value: any,
        accessToken: string
    ): Promise<{ status: { result: 1 | 0; isSameState: 0 | 1 } }> {
        try {
            const res = await fetch('http://localhost:3000/xiaomi/device/control', {
                method: 'POST',
                headers: {
                    access_token: accessToken,
                    app_id: this.config.app_id,
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    did,
                    control: {
                        operation,
                        value,
                    },
                }),
            });

            const json = await res.json();

            if (res.status !== 200) {
                let errorMessage: string = json.message || `HTTP错误: ${res.status}`;
                const errCode = json.code ?? res.status;

                switch (json.code) {
                    case 903:
                        errorMessage = '授权过期';
                        break;
                    case 1:
                        errorMessage = '设备不存在';
                        break;
                    case 3:
                        errorMessage = '属性不存在';
                        break;
                    case 43:
                        errorMessage = '属性值错误';
                        break;
                }
                throw new Error(errorMessage + ` (code: ${errCode})`);
            }


            if (json.code !== 200) {
                let errorMessage: string;
                switch (json.code) {
                    case 903:
                        errorMessage = '授权过期';
                        break;
                    case 1:
                        errorMessage = '设备不存在';
                        break;
                    case 3:
                        errorMessage = '属性不存在';
                        break;
                    case 43:
                        errorMessage = '属性值错误';
                        break;
                    default:
                        errorMessage = json.message || '小米控制API返回非200 code';
                        break;
                }
                throw new Error(errorMessage + ` (code: ${json.code})`);
            }


            if (json.status !== 1 && json.isSameState === 1) {
                console.log(`[XiaomiControl] 设备 ${did} 状态已是 ${operation} = ${value}，无需改变。`);
                return {
                    status: {
                        result: 1,
                        isSameState: 1
                    }
                };
            } else if (json.status !== 1) {
                throw new Error(`小米设备 ${did} 操作 ${operation} 未成功 (result: ${json.status})`);
            }

            console.log(`[XiaomiControl] 成功控制 ${did}：${operation} = ${value}`);


            return {
                status: {
                    result: 1,
                    isSameState: json.isSameState ?? 0
                }
            };

        } catch (error: any) {
            console.error(`[XiaomiControl Error] 控制设备 ${did} 失败:`, error.message);
            throw error;
        }
    }

}
